home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / xdme_1.84_src.lha / XDME / Src / Var / vars.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-04  |  18.2 KB  |  637 lines

  1.  
  2. /******************************************************************************
  3.  
  4.     MODULE
  5.     Vars.c
  6.  
  7.     DESCRIPTION
  8.     the vars-module shall support access to different types of
  9.     variables
  10.     which are currently "special" vars/flags, "global" vars/flags,
  11.     "textlocal" vars/flags, "macrolocal" vars and "env" vars
  12.     also keybindings and menuitems are accessible via variables
  13.     in some versions of xdme also rexxclips, rexxvars, and macro-bodies
  14.     might be accessible via the variable interface, but that feature
  15.     has been dropped due to less feedback
  16.     (there are some other types used for DME, but not for XDME yet)
  17.  
  18.     NOTES
  19.     This Module is a collection of some
  20.     types/trees of variables together
  21.     with their command interface functions;
  22.  
  23.     it contains also the standardized
  24.     access functions to get and set
  25.     any variable w/ one function.
  26.  
  27.     WARNING:
  28.     as this module is written very close to XDME's
  29.     internal hierachy; in fact, that means, that
  30.     funcionality is dropped as soon, as the
  31.     C-Interpreter is available
  32.  
  33.     BUGS
  34.     none known
  35.  
  36.     TODO
  37.     tell me
  38.  
  39.     EXAMPLES
  40.  
  41.     SEE ALSO
  42.  
  43.     INDEX
  44.  
  45.     HISTORY
  46.     ??-??-9? b_noll created
  47.  
  48. ******************************************************************************/
  49.  
  50.  
  51. /**************************************
  52.           Includes
  53. **************************************/
  54.  
  55. #include "defs.h"
  56.  
  57. /**************************************
  58.         Global Variables
  59. **************************************/
  60.  
  61.  
  62. /**************************************
  63.       Internal Defines & Structures
  64. **************************************/
  65.  
  66. #ifndef SIGN_LOCAL_FLAG
  67. # define SIGN_LOCAL_FLAG 't'
  68. #endif
  69.  
  70. #define PROC void*
  71.  
  72. /**************************************
  73.        Internal Variables
  74. **************************************/
  75.  
  76.  
  77. /**************************************
  78.        Internal Prototypes
  79. **************************************/
  80.  
  81.  
  82. /**************************************
  83.          Macros
  84. **************************************/
  85.  
  86.  
  87. /**************************************
  88.          Implementation
  89. **************************************/
  90.  
  91.  
  92. #ifdef DBASE
  93. # define tg      DmeBase.gflags
  94. # define VarsTree DmeBase.SList
  95. #else
  96. char tg[MAXTOGGLE/8];
  97. APTR VarsTree = NULL;
  98. #endif /* DBASE */
  99.  
  100.  
  101.  
  102. /*
  103. **  init_variables()
  104. **    initialize the "global" variables structures
  105. **    call that function from main or make it '__autoinit'
  106. */
  107.  
  108. //Prototype void init_variables (void);
  109. /* void init_variables (void)
  110. {
  111.     VarsTree = NULL;
  112.     setmem(tg, sizeof(tg), 0);
  113. } /* init_variables */
  114.  
  115.  
  116.  
  117.  
  118. /***************************************************************
  119. **        Access to Environment variables
  120. ***************************************************************/
  121.  
  122. static UBYTE *GetDEnv (const UBYTE *ename) {
  123.     UBYTE *str = NULL;
  124.  
  125. #ifdef AMIGA
  126.     long siz;
  127.     UBYTE buffer[LINE_LENGTH];
  128.  
  129.     if ((siz = GetVar (ename, buffer, LINE_LENGTH, 0)) >= 0)
  130.     if ((str = malloc (siz + 1)))
  131.         strcpy (str, buffer);
  132.     else
  133.         nomemory();
  134.     return str;
  135. #endif
  136.  
  137. #ifdef UNIX
  138.     if ((str = getenv (ename)))
  139.     if ((str = strdup(str)))
  140.         return str;
  141.     else
  142.         nomemory();
  143.     return NULL;
  144. #endif
  145.  
  146. } /* GetDEnv */
  147.  
  148. static void SetDEnv (const UBYTE *ename, const UBYTE *econt) {
  149. #ifdef AMIGA
  150.     SetVar (ename, econt, -1, GVF_GLOBAL_ONLY);
  151. #endif
  152. #ifdef UNIX
  153.     setenv (ename, econt, TRUE);
  154. #endif
  155. } /* SetDEnv */
  156.  
  157. static UBYTE *GetEnvVar (const UBYTE *name) {
  158.     UBYTE *str;
  159.  
  160.     mountrequest(0);
  161.     str = GetDEnv(name);
  162.     mountrequest(1);
  163.     return str;
  164. } /* GetEnvVar */
  165.  
  166. /*DEFHELP #cmd var SETENV var str  -create/modify an enviroment variable (ENV:) */
  167. DEFUSERCMD("SetENV", 2, CF_VWM|CF_COK|CF_ICO, void, do_setenv, (void),)
  168. {
  169.     SetDEnv (av[1], av[2]);
  170. } /* do_setenv */
  171.  
  172. /*DEFHELP #cmd var UNSETENV var    -delete an enviroment variable (ENV:) */
  173. DEFUSERCMD("UnsetENV", 1, CF_VWM|CF_COK|CF_ICO, void, do_unsetenv, (void),)
  174. {
  175. #ifdef AMIGA
  176.     DeleteVar (av[1], 0);
  177. #endif
  178. #ifdef UNIX
  179.     unsetenv(av[1]);
  180. #endif
  181. } /* do_unsetenv */
  182.  
  183. DEFVARTREE( 90, "ENV_", VAR_ENV, 4, 4, 0, NULL, NULL, SetDEnv, GetEnvVar )
  184.  
  185.  
  186.  
  187.  
  188.  
  189. /***************************************************************
  190. **    Access to the different kinds of Flags
  191. ***************************************************************/
  192.  
  193.  
  194. /***************************************************************
  195. **        Handling of TEXT Local Flags
  196. ***************************************************************/
  197.  
  198. DEFVARTREE( 30, "TFLAG_", VAR_TF, 6, 6, 0, NULL, NULL, SetTextFlag, GetTextFlag )
  199.  
  200. Prototype int is_tflagset (int);
  201. int is_tflagset (int num)
  202. {
  203.     return IsFlagSet (Ep->textflags, num, MAX_TEXTFLAGS);
  204. } /* is_tflagset */
  205.  
  206. static char SetTextFlag (const UBYTE *name, const UBYTE *value) {
  207.     return SetFlag (Ep->textflags, name, value, MAX_TEXTFLAGS, "t");
  208. } /* SetTextFlag */
  209.  
  210. UBYTE *GetTextFlag (const UBYTE *name) {
  211.     return GetFlag(Ep->textflags, name, MAX_TEXTFLAGS, "t");
  212. } /* GetTextFlag */
  213.  
  214.  
  215.  
  216.  
  217.  
  218. /***************************************************************
  219. **        Handling of DME Global Flags
  220. ***************************************************************/
  221.  
  222. DEFVARTREE( 40, "GFLAG_", VAR_GF, 6, 6, 0, NULL, NULL, SetGlobalFlag, GetGlobalFlag )  /* ifdef PATCH_PACK set replace to "g%s" */
  223.  
  224. Prototype int is_gflagset (int);
  225. int is_gflagset (int num)
  226. {
  227.     return IsFlagSet (tg, num, MAXTOGGLE);
  228. } /* is_gflagset */
  229.  
  230. static char SetGlobalFlag (const UBYTE *name, const UBYTE *value) {
  231.     return SetFlag (tg, name, value, MAXTOGGLE, ""); /* "g" */
  232. } /* SetGlobalFlag */
  233.  
  234. static UBYTE *GetGlobalFlag (const UBYTE *name) {
  235.     return GetFlag (tg, name, MAXTOGGLE, "");   /* "g" */
  236. } /* GetGlobalFlag */
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243. /***************************************************************
  244. **  Access to the different kinds of Named Variables
  245. ***************************************************************/
  246.  
  247. /***************************************************************
  248. **        Handling of DME "global" Variables
  249. ***************************************************************/
  250.  
  251. DEFVARTREE( 70, "GVAR_", VAR_GV, 5, 5, VF_COP, &VarsTree, NULL, SetVarIntoTree, GetVarFromTree )
  252.  
  253. /*static UBYTE *GetDMEVar (const UBYTE *name) {
  254.     return GetVarFromTree(&VarsTree, name);
  255. } /* GetDMEVar */
  256.  
  257. /*static void SetDMEVar (const UBYTE *name, const UBYTE *value) {
  258.     SetVarIntoTree (&VarsTree, name, value);
  259. } /* SetDMEVar */
  260.  
  261. /*DEFHELP #cmd var SET var str       -create/modify an internal variable */
  262. DEFUSERCMD("Set", 2, CF_VWM|CF_COK|CF_ICO, void, do_set, (void),)
  263. {
  264.     if (!SetGlobalFlag(av[1], av[2]))
  265.     SetVarIntoTree (&VarsTree, av[1], av[2]);
  266. } /* do_set */
  267.  
  268. /*DEFHELP #cmd var UNSET var       -delete an internal variable */
  269. DEFUSERCMD("Unset", 1, CF_VWM|CF_COK|CF_ICO, void, do_unset, (void),)
  270. {
  271.     DelVarFromTree (&VarsTree, av[1]);
  272. } /* do_unset */
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279. /***************************************************************
  280. **        Handling of Text Local Variables
  281. ***************************************************************/
  282.  
  283. DEFVARTREE( 60, "TVAR_", VAR_TV, 5, 5, VF_COP|VF_PROJECT, (APTR)(offsetof(ED,textvars)), NULL, SetVarIntoTree, GetVarFromTree )
  284.  
  285. /*static UBYTE *GetTextVar (const UBYTE *name) {
  286.     return GetVarFromTree (&Ep->textvars, name);
  287. } /* GetTextVar */
  288.  
  289. /*static void SetTextVar (const UBYTE *name, const UBYTE *value) {
  290.     SetVarIntoTree (&Ep->textvars, name, value);
  291. } /* SetTextVar */
  292.  
  293. /*DEFHELP #cmd var SETTVAR var str     -create/modify a text-local variable */
  294. DEFUSERCMD("SetTVar", 2, CF_VWM|CF_ICO|CF_COK, void, do_settvar, (void),)
  295. {
  296.     if (!SetTextFlag(av[1], av[2]))
  297.     SetVarIntoTree (&Ep->textvars, av[1], av[2]);
  298. } /* do_settvar */
  299.  
  300. /*DEFHELP #cmd var UNSETTVAR var       -delete a text-local variable */
  301. DEFUSERCMD("UnsetTVar", 1, CF_VWM|CF_ICO|CF_COK, void, do_unsettvar, (void),)
  302. {
  303.     DelVarFromTree (&Ep->textvars, av[1]);
  304. } /* do_unsettvar */
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311. /***************************************************************
  312. **    Interface to come around with all types of flags
  313. ***************************************************************/
  314.  
  315. static char SetAnyFlag (const UBYTE *name, const UBYTE *qual) {
  316.     if (name && qual) {
  317.     if (is_number (name)) {
  318.         return SetGlobalFlag (name, qual);
  319.  
  320. //    } if (!is_digit(name[1])) {             /* Commented out for XDME */
  321. //         return(SetSpecialVar (name, qual));/* Commented out for XDME */
  322.  
  323.     } else if (name[0] == SIGN_LOCAL_FLAG) {
  324.         return SetTextFlag(name, qual);
  325.  
  326.     } else {
  327.         /* SET_ABORTION( 1 ); */
  328.         return 0;
  329.     } /* if */
  330.     } else {
  331.     SET_ABORTION( 1 );
  332.     return 0;
  333.     } /* if */
  334. } /* SetAnyFlag */
  335.  
  336. /*DEFHELP #cmd var FLAG name what  -change flag @{B}name@{UB} by @{B}what@{UB}
  337. with @{B}name@{UB} is number for a global flag or "t"number for a textlocal flag;
  338. @{B}what@{UB} is one of {on, off, toggle, switch, 0, 1, set, reset, true, false}; */
  339. DEFUSERCMD("Flag", 2, CF_VWM|CF_COK|CF_ICO, void, do_flag, (void),)
  340. {
  341.     if (!SetAnyFlag(av[1],av[2]))
  342.     SET_ABORTION( 1 );
  343. } /* do_flag */
  344.  
  345.  
  346. /*DEFHELP #cmd var SETTOGGLE flag     -clear toggle entry @{B}flag@{UB} = 0..255|t0..t31 */
  347. DEFUSERCMD("ResetToggle", 1, CF_VWM|CF_COK|CF_ICO, void, do_toggleflag, (void),;)
  348.  
  349. /*DEFHELP #cmd var SETTOGGLE flag     -set toggle entry @{B}flag@{UB} = 0..255|t0..t31 */
  350. DEFUSERCMD("SetToggle", 1, CF_VWM|CF_COK|CF_ICO, void, do_toggleflag, (void),;)
  351.  
  352. /*DEFHELP #cmd var SETTOGGLE flag     -flip toggle entry @{B}flag@{UB} = 0..255|t0..t31 */
  353. DEFUSERCMD("Toggle", 1, CF_VWM|CF_COK|CF_ICO, void, do_toggleflag, (void),)
  354. {
  355.     SetAnyFlag (av[1], av[0]);
  356. } /* do_toggleflag */
  357.  
  358.  
  359.  
  360. DEFVARTREE( 10, "?", VAR_TEST, 1,1, VF_COP|VF_PAW, NULL, NULL, NULL, ExistsAnyVar )
  361.  
  362. UBYTE *ExistsAnyVar (const UBYTE *name)
  363. {
  364.     UBYTE *buffer;
  365.     int inter_abort = IS_ABORTED(), type = VAR_NEX;
  366.  
  367.     SET_ABORTION( 0 );
  368.     if ((buffer = GetTypedVar (name, &type))) {
  369.     free (buffer);
  370.     } /* if */
  371.  
  372.     SET_ABORTION(inter_abort);
  373.     return (type != VAR_NEX)? "1": "0";
  374. } /* ExistsAnyVar */
  375.  
  376.  
  377.  
  378.  
  379. /*************************************************************************
  380. **
  381. **  Interface to be used for external functions and commands
  382. **
  383. *************************************************************************/
  384.  
  385.  
  386.  
  387. /*
  388. ** the different types of "variables",
  389. ** which seem to be possible to be recognized
  390. **
  391. ** these definitions must be visible to all modules
  392. */
  393.  
  394.  
  395. #define VF_COP        1  /* duplicate the result             */
  396. #define VF_PAW        2  /* Prefix AlWays: dont use without Prefix */
  397. #define VF_PROJECT  4  /* Userdata is actually offset to Project */
  398. #define VF_UD_FUNC  8  /* Userdata is actually function      */
  399.  
  400. /* do _NEVER_ use VF_PROJECT and VF_UD_FUNC together!!!!! */
  401.  
  402.  
  403. typedef struct _vtype
  404. {
  405.     const char *name;        /* prefix */
  406.     int     id;        /* number for communication */
  407.     int     len;        /* size of prefix for comparison */
  408.     int     offset;     /* offset to cut prefix */
  409.     int     flags;        /* flags (e.g. duplicate result ...) */
  410.     char       *replace;    /* if prefix matches, replace w/that prefix */
  411.     void      (*do_set)(UBYTE *, UBYTE *); /* set-function */
  412.     UBYTE*     (*do_get)(UBYTE *);         /* get-function */
  413.     APTR    userdata;
  414. } VTYPE;
  415.  
  416.  
  417. static VTYPE vartypes[] =
  418. {
  419. #undef    DEFVARTREE
  420. #define DEFVARTREE(prio,prefix,id,prelen,precut,flags,ud,replace,set,get) \
  421.            prefix,id,prelen,precut,flags,replace,(PROC)set,(PROC)get,ud,
  422.  
  423. //DEFVARTREE( "SHVAR_",  VAR_SH , 6, 6,             0, NULL, NULL, NULL )
  424. //DEFVARTREE( "ARP_",    VAR_MNX, 4, 4,             0, NULL, NULL, NULL )
  425. //DEFVARTREE( "RXFUNC ", VAR_RXF, 7, 7,             0, NULL, NULL, getQ )
  426. //DEFVARTREE( "RXSFUNC ",VAR_RXF, 8, 8,             0, NULL, NULL, getQ )
  427. //DEFVARTREE( "SFLAG_",  VAR_SF,  6, 6,             0, NULL,     (void (*)(char*,char*))SetSpecialFlag, GetSpecialFlag )    /* we need 3 names */
  428. //DEFVARTREE( "SINT_",   VAR_SI,  5, 5,             0, NULL,     (void (*)(char*,char*))SetSpecialInt,  GetSpecialInt )     /* for the 3 different types (or we have to put them together) */
  429. //DEFVARTREE( "SPC_",    VAR_SV,  4, 4,             0, NULL,     (void (*)(char*,char*))SetSpecialVar,  GetSpecialVar )     /* of special vars else there are big problems */
  430. //DEFVARTREE( "RXCLP_",  VAR_CLP, 6, 6,             0, NULL,     SetRexxClip,    GetRexxClip  )
  431. //DEFVARTREE( "RXVAR_",  VAR_RXX, 6, 6,             0, NULL,     setrexxvar,     getrexxvar   )
  432. //DEFVARTREE( "arg",     VAR_ARG, 3, 0,           VF_PAW, NULL, NULL,     NULL,           getmacroarg )
  433. //DEFVARTREE( "ARG_",    VAR_ARG, 4, 4,           VF_PAW, NULL, "arg%s",  NULL,           getmacroarg )
  434. //DEFVARTREE( "?",       VAR_TEST,1, 1,    VF_COP|VF_PAW, NULL, NULL,     NULL,           (PROC)ExistsAnyVar )            /* does a certain variable exist */
  435. //DEFVARTREE( "SPC_",    VAR_SV,  4, 4,                0, NULL, NULL,     (PROC)SPC_set,  (PROC)SPC_get )                 /* all spc vars put together */
  436. //DEFVARTREE( "TFLAG_",  VAR_TF,  6, 6,                0, NULL, "t%s",    (PROC)SetTextFlag,  (PROC)GetTextFlag )
  437. //DEFVARTREE( "GFLAG_",  VAR_GF,  6, 6,                0, tg, NULL,       (PROC)SetGlobalFlag,(PROC)GetGlobalFlag )  /* ifdef PATCH_PACK set replace to "g%s" */
  438. //DEFVARTREE( "MVAR_",   VAR_MV,  5, 5,VF_COP|VF_UD_FUNC, GetMVBase, NULL,                    (PROC)SetVarIntoTree, (PROC)GetVarFromTree )
  439. //DEFVARTREE( "TVAR_",   VAR_TV,  5, 5,VF_COP|VF_PROJECT, (APTR)offsetof(ED,textvars), NULL,  (PROC)SetVarIntoTree, (PROC)GetVarFromTree )
  440. //DEFVARTREE( "GVAR_",   VAR_GV,  5, 5,           VF_COP, &VarsTree, NULL,                    (PROC)SetVarIntoTree, (PROC)GetVarFromTree )
  441. //DEFVARTREE( "LNODE_",  VAR_LN,  6, 6, VF_COP, NULL, NULL, (PROC)SetLNode,  (PROC)GetLNode )
  442. //DEFVARTREE( "ENV_",    VAR_ENV, 4, 4,                0, NULL, NULL,     (PROC)SetDEnv,  (PROC)GetEnvVar )
  443. //DEFVARTREE( "KEY_",    VAR_MAP, 4, 4,           VF_COP, NULL, NULL,     (PROC)mapkey,   (PROC)keyspectomacro )
  444. //DEFVARTREE( "MENU_",   VAR_MEN, 5, 5,           VF_COP, NULL, NULL,     NULL,           (PROC)menutomacro )
  445. #include "gen_vtrees.h"
  446. /*
  447. DEFVARTREE( ff, NULL,      VAR_NEX, 0, 0,                0, NULL, NULL,     NULL, NULL )
  448. */
  449. };
  450.  
  451. int check_vtype (char *name, char **rname, int *type)
  452. {
  453.     const VTYPE *vt;
  454.  
  455.     for (vt = vartypes; vt->id != VAR_NEX && !IS_ABORTED(); vt++) {
  456.     if (strncmp(name, vt->name, vt->len) == 0) {
  457.         *rname = name+vt->offset;
  458.         if (vt->replace) {
  459.         sprintf(tmp_buffer, vt->replace, *rname);
  460.         *rname = tmp_buffer;
  461.         } /* if prefix replacement */
  462.         *type = vt->id;
  463.         return 1;
  464.     } /* if */
  465.     } /* for */
  466.     return 0;
  467. } /* check_vtype */
  468.  
  469.  
  470.  
  471. /*
  472. **  GetTypedVar()
  473. **    this function is nearly the same as getvar from cmd2.c
  474. **    major differences:
  475. **    * it tells where it has found a variable;
  476. **    * first we check if the search-name matches a certain
  477. **      type-prefix and if it does, we use that type and its
  478. **      result (w/out respect if result != NULL)
  479. **    * then we check all types until we get a non-NULL result
  480. **      or an abortion
  481. **    * the end of the vartypes-list means - there is no variable
  482. **      of that name
  483. **    (type may be NULL)
  484. */
  485.  
  486. Prototype char *GetTypedVar (const char *find, int *type);
  487. char *GetTypedVar (const char *find, int *type)
  488. {
  489.     char    *found         = NULL;
  490.     int      itype         = VAR_NEX;
  491.     const VTYPE *vt;
  492.     char     inter_abort = IS_ABORTED();
  493.     int      has_pf = 0;
  494.  
  495.     if (type)
  496.     *type = VAR_NEX;
  497.  
  498.     if ((find == NULL)) {
  499.     SET_ABORTION( 1 );
  500.     return NULL;
  501.     } /* if !name corrupt */
  502.  
  503.  
  504.     if ((find[0] == '\0')) { /* is it a name ? */
  505.     /* we do not set abortcommand here, since this could be a
  506.     call from a lonely "$" */
  507.     return NULL;
  508.     } /* if name corrupt */
  509.  
  510.  
  511.  
  512. if (globalflags._debug) printf("\tgetvar:oerr/val == %s/%d\n", find, (int)IS_ABORTED());
  513.  
  514.  
  515.     SET_ABORTION( 0 );
  516.  
  517.     has_pf = check_vtype(find, &find, &itype);
  518.  
  519.     for (vt = vartypes; vt->id != VAR_NEX && !IS_ABORTED(); vt++) {
  520.     if (itype != VAR_NEX && itype != vt->id)
  521.         continue;
  522.     if ((itype == VAR_NEX) && (vt->flags & VF_PAW))
  523.         continue;
  524.     if (vt->do_get) {
  525.         if (vt->userdata) {
  526.         APTR *inter = vt->userdata;
  527.         if (vt->flags & VF_PROJECT)
  528.             inter = (APTR)((ULONG)Ep + (ULONG)inter);
  529.         if (vt->flags & VF_UD_FUNC)
  530.             inter = ((APTR (*)(void))inter)();
  531.         if (inter)
  532.             found = ((UBYTE *(*)(APTR, UBYTE *))vt->do_get)(inter, find);
  533.         } else {
  534.         found = (*vt->do_get)(find);
  535.         } /* if */
  536.         if (found) {
  537.         itype = vt->id;
  538.         if (vt->flags & VF_COP) {
  539.             found = strdup(found);
  540.         } /* if dup'd */
  541.         goto gv_quit;
  542.         } /* if res#0 */
  543.     } /* if ex det-func */
  544.     } /* for all types */
  545.  
  546. gv_quit:
  547.  
  548. if (globalflags._debug) printf("\tgetvar:prefix/err/val == %s/%d/%s\n",vt->name, (int)IS_ABORTED(), found);
  549.  
  550.     SET_ABORTION( IS_ABORTED() || inter_abort );
  551.     if (type)
  552.     *type = itype;
  553.     return found;
  554.  
  555. } /* GetTypedVar */
  556.  
  557.  
  558.  
  559. /*
  560. **  Set a Variable
  561. **    if it has a known type, use the associated set-command
  562. **    else check if there is a matching prefix
  563. **    if nothing fits - abort
  564. */
  565.  
  566. Prototype int SetTypedVar (const char *name, const char *value, int type);
  567. int SetTypedVar (const char *name, const char *value, int type)
  568. {
  569.     const VTYPE *vt;
  570.  
  571.     if ((name == NULL) || (name[0] == '\0')) { /* is it a name ? */
  572.     SET_ABORTION( 1 );
  573.     return 0;
  574.     } /* if name corrupt */
  575.  
  576.     if (type == VAR_NEX) {
  577.     if (!check_vtype(name, &name, &type)) {
  578.         SET_ABORTION( 1 );
  579.         return 0;
  580.     } /* if not prefixed */
  581.     } /* if unknown type */
  582.  
  583.     for (vt = vartypes; vt->id != VAR_NEX; vt++) {
  584.     if (vt->id == type) {
  585.         if (vt->do_set) {
  586.         char *ptr = name;
  587.         if (strncmp(ptr, vt->name, vt->len) == 0) {
  588.             ptr = name+vt->offset;
  589.             if (vt->replace) {
  590.             sprintf(tmp_buffer, vt->replace, ptr);
  591.             ptr = tmp_buffer;
  592.             } /* if prefix replacement */
  593.         } /* if (no) matching prefix */
  594.         if (vt->userdata) {
  595.             APTR *inter = vt->userdata;
  596.             if (vt->flags & VF_PROJECT)
  597.             inter = (APTR)((ULONG)Ep + (ULONG)inter);
  598.             if (vt->flags & VF_UD_FUNC)
  599.             inter = ((APTR (*)(void))inter)();
  600.             if (inter)
  601.             ((int (*)(APTR, UBYTE *, UBYTE *))vt->do_set)(inter, ptr, value);
  602.         } else {
  603.             (*vt->do_set)(ptr, value);
  604.         } /* if */
  605.         return 1;
  606.         } else {
  607.         SET_ABORTION( 1 );
  608.         return 0;
  609.         } /* if (no) set-function */
  610.     } /* if id found */
  611.     } /* for all types */
  612.  
  613.     SET_ABORTION( 1 );
  614.     return 0;
  615. } /* SetTypedVar */
  616.  
  617.  
  618.  
  619. /*
  620. **  Search
  621. **  (1) special Variables (2) Flags (3) macro's list,
  622. **  (4) text's list, (5) internal list, (6) enviroment,
  623. **  (7) Rexx cliplist (8) macros.  The variable is allocated
  624. **  with malloc().  NULL if not found.  ENV: need not exist.
  625. */
  626.  
  627. Prototype char *getvar (const char *find);
  628. char *getvar (const char *find)
  629. {
  630.     return GetTypedVar (find, NULL);
  631. } /* getvar */
  632.  
  633. /******************************************************************************
  634. *****  END Vars.c
  635. ******************************************************************************/
  636.  
  637.